﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Constructor
{
    public partial class RegularPart : UserControl
    {
        Slot _slot;
        public RegularPart()
        {
            InitializeComponent();
        }
        public RegularPart(Slot slot)
        {
            InitializeComponent();
            _slot = slot;
            Enabled = !(slot.Frame.Name == "Клетка");
            cmb_domain.Enabled = !(slot.Frame.Name == "Объект") && slot.isOwn;
            Init();
        }
        private void FillDomainCmb()
        {
            DataTable dt = External.ds.Tables["domens"];
            foreach (DataRow dr in dt.Rows)
                cmb_domain.Items.Add(dr["Название_домена"].ToString());
            cmb_domain.Items.Add("Images");
        }
        public void Init()
        {
            cmb_domain.SelectedIndexChanged -= cmb_domain_SelectedIndexChanged;
            cmb_default.SelectedIndexChanged -= cmb_default_SelectedIndexChanged;
            //cmb_domain.DataSource = new DataView(External.ds.Tables["domens"]);
            //cmb_domain.DisplayMember = "Название_домена";
            FillDomainCmb();
            cmb_default.DataSource = new DataView(External.ds.Tables["domens_params"]);
            cmb_default.DisplayMember = "Значения домена";
            cmb_domain.SelectedIndexChanged += cmb_domain_SelectedIndexChanged;
            cmb_default.SelectedIndexChanged += cmb_default_SelectedIndexChanged;
            if (cmb_domain.Items.Count > 0 && string.IsNullOrEmpty(_slot.DomainID))
                cmb_domain.SelectedIndex = 0;
            if (cmb_default.Items.Count > 0 && _slot.Default == null)
                cmb_default_SelectedIndexChanged(null, null);
            switch (_slot.Inherit)
            {
                case CommonLib.TypeInherit.Overwrite:
                    cmb_inh.SelectedIndex = 0;
                    break;
                case CommonLib.TypeInherit.Same:
                    cmb_inh.SelectedIndex = 1;
                    break;
                case CommonLib.TypeInherit.Range:
                    cmb_inh.SelectedIndex = 2;
                    break;
            }
            cmb_domain.Text = _slot.DomainID;
            if (_slot.DomainID != null)
            {
                if (_slot.DomainID == "Images" && _slot.Default != null)
                {
                    if (External.images.LoadedImages != null && External.images.LoadedImages.ContainsKey(_slot.Default.ToString()))
                        img_value.BackgroundImage = External.images.LoadedImages[_slot.Default.ToString()].BackgroundImage;
                    img_value.Tag = _slot.Default;
                    return;
                }
                if (_slot.Domain.Type == CommonLib.DomainType.Enum && _slot.Default != null)
                    cmb_default.Text = _slot.Default.ToString();
                if (_slot.Domain.Type == CommonLib.DomainType.Number && _slot.Default != null && _slot.Default.ToString() != "" && _slot.Inherit != CommonLib.TypeInherit.Range)
                {
                    int temp = 0;
                    if (int.TryParse(_slot.Default.ToString(), out temp) && temp >= numUpDown_value.Minimum && temp <= numUpDown_value.Minimum)
                        numUpDown_value.Value = temp;
                }
                else
                    if (_slot.Domain.Type == CommonLib.DomainType.Number && _slot.Default != null && _slot.Inherit == CommonLib.TypeInherit.Range)
                    {
                        int max = 0;
                        int min = 0;
                        if (int.TryParse(_slot.Default.ToString().Split(new string[] { ".." }, StringSplitOptions.None)[0], out min) &&
                            int.TryParse(_slot.Default.ToString().Split(new string[] { ".." }, StringSplitOptions.None)[1], out max))
                        {
                            if (min >= numUpDown_min.Minimum)
                                numUpDown_min.Value = min;
                            if (max <= numUpDown_max.Maximum)
                                numUpDown_max.Value = max;
                        }
                    }
            }
            cmb_domain_SelectedIndexChanged(null, null);
        }

        void cmb_domain_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cmb_domain.SelectedItem != null && cmb_domain.Text!=_slot.DomainID)
            {
                (cmb_default.DataSource as DataView).RowFilter = "Название_домена = '"
                    + cmb_domain.SelectedItem.ToString() + "'";
                _slot.DomainID = cmb_domain.SelectedItem.ToString();
                _slot.RepaintItem();
                switch (_slot.Domain.Type)
                {
                    case CommonLib.DomainType.Enum:
                        _slot.Default = _slot.Domain.Values[0];
                        break;
                    case CommonLib.DomainType.Number:
                        _slot.Default = _slot.Domain.MinValue;
                        break;
                }
                ChangeVisibles();
            }
        }
        private void ChangeVisibleRange()
        {
            if (_slot.Domain.Type == CommonLib.DomainType.Enum)
            {
                if (cmb_inh.Items.Count == 3)
                    cmb_inh.Items.RemoveAt(2);
            }
            else
                if (cmb_inh.Items.Count == 2)
                    cmb_inh.Items.Insert(2, "Range");
        }
        private void ChangeVisibles()
        {
            Domain d = _slot.Domain;
            if (d != null)
            {
                switch (d.Type)
                {
                    case CommonLib.DomainType.Enum:
                        cmb_default.Visible = true;
                        numUpDown_value.Visible = false;
                        numUpDown_min.Visible = false;
                        numUpDown_max.Visible = false;
                        img_value.Visible = false;
                        break;
                    case CommonLib.DomainType.Image:
                        img_value.Visible = true;
                        numUpDown_min.Visible = false;
                        numUpDown_max.Visible = false;
                        numUpDown_value.Visible = false;
                        cmb_default.Visible = false;
                        break;
                    case CommonLib.DomainType.Number:
                        cmb_default.Visible = false;
                        img_value.Visible = false;
                        if (_slot.Inherit == CommonLib.TypeInherit.Range)
                        {
                            numUpDown_min.Visible = true;
                            numUpDown_max.Visible = true;
                            numUpDown_value.Visible = false;
                            numUpDown_max.ValueChanged -= numUpDown_max_ValueChanged;
                            numUpDown_min.ValueChanged -= numUpDown_min_ValueChanged;
                            numUpDown_min.Minimum = _slot.Domain.MinValue;
                            numUpDown_min.Maximum = _slot.Domain.MaxValue;
                            numUpDown_max.Minimum = _slot.Domain.MinValue;
                            numUpDown_max.Maximum = _slot.Domain.MaxValue;
                            numUpDown_max.ValueChanged += numUpDown_max_ValueChanged;
                            numUpDown_min.ValueChanged += numUpDown_min_ValueChanged;
                            if (_slot.Default == null || !_slot.Default.ToString().Contains(".."))
                            {
                                numUpDown_min_ValueChanged(null, null);
                                numUpDown_max_ValueChanged(null, null);
                            }
                        }
                        else
                        {
                            numUpDown_value.ValueChanged -= numUpDown_value_ValueChanged;
                            numUpDown_min.Visible = false;
                            numUpDown_max.Visible = false;
                            numUpDown_value.Visible = true;
                            numUpDown_value.Minimum = d.MinValue;
                            numUpDown_value.Maximum = d.MaxValue;
                            numUpDown_value.ValueChanged += numUpDown_value_ValueChanged;
                            if (_slot.Default==null || _slot.Default.ToString()=="")
                                numUpDown_value_ValueChanged(null, null);
                        }
                        break;
                }
            }
        }
        private void UpdateParentSlot()
        {
            Frame f = _slot.Frame;
            if (!_slot.isOwn && f.SearchSlot(_slot.Name) == null)
            {
                Slot s = _slot.Clone(f);
                f.Slots.Add(s);
                _slot = s;
            }
        }
        private void numUpDown_value_ValueChanged(object sender, EventArgs e)
        {
            _slot.Default = numUpDown_value.Value;
            UpdateParentSlot();
        }

        private void cmb_default_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cmb_default.SelectedItem != null)
                _slot.Default = (cmb_default.SelectedItem as DataRowView)["Значения домена"].ToString();
            UpdateParentSlot();
        }

        private void cmb_inh_SelectedIndexChanged(object sender, EventArgs e)
        {
            switch (cmb_inh.SelectedIndex)
            {
                case 0:
                    _slot.Inherit = CommonLib.TypeInherit.Overwrite;
                    break;
                case 1:
                    _slot.Inherit = CommonLib.TypeInherit.Same;
                    break;
                case 2:
                    _slot.Inherit = CommonLib.TypeInherit.Range;
                    break;
            }
            ChangeVisibles();
            UpdateParentSlot();
        }

        private void numUpDown_min_ValueChanged(object sender, EventArgs e)
        {
            numUpDown_max.Minimum = numUpDown_min.Value;
            _slot.Default = numUpDown_min.Value.ToString() + ".." + numUpDown_max.Value.ToString();
            UpdateParentSlot();
        }

        private void numUpDown_max_ValueChanged(object sender, EventArgs e)
        {
            numUpDown_min.Maximum = numUpDown_max.Value;
            _slot.Default = numUpDown_min.Value.ToString() + ".." + numUpDown_max.Value.ToString();
            UpdateParentSlot();
        }

        private void img_value_Click(object sender, EventArgs e)
        {
            ImagePicker picker = new ImagePicker(sender as PictureBox);
            picker.Location = MousePosition;
            picker.ShowDialog();
        }

        private void img_value_BackgroundImageChanged(object sender, EventArgs e)
        {
            _slot.Default = img_value.BackgroundImage.Tag.ToString();
            UpdateParentSlot();
        }

        #region Контекстное пополнение

        private bool ContainsDomain(ComboBox cmb, string domain)
        {
            foreach (Object str in cmb.Items)
                if (str.ToString().ToUpper() == domain.ToUpper()) return true;
            return false;
        }
        private bool ContainsValue(ComboBox cmb, string value)
        {
            foreach (Object str in cmb.Items)
                if ((str as DataRowView)["Значения домена"].ToString().ToUpper() == value.ToUpper()) return true;
            return false;
        }
        private void cmb_domain_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
                AddDomain(cmb_domain.Text.Trim());
        }

        private void cmb_domain_Leave(object sender, EventArgs e)
        {
            AddDomain(cmb_domain.Text.Trim());
        }
        private void AddDomain(string text)
        {
            if (text != "" && !ContainsDomain(cmb_domain, text))
            {
                External.ds.Tables["domens"].Rows.Add(text);
                AddValue("Да", text);
                AddValue("Нет", text);
                cmb_domain.Items.Add(text);
                cmb_domain.Text = text;
            }
        }
        private void AddDomain(string text, string parent_domain)
        {
            External.ds.Tables["domens"].Rows.Add(text);
            foreach (Object str in cmb_default.Items)
                AddValue((str as DataRowView)["Значения домена"].ToString(), text);
            cmb_domain.Items.Add(text);
            cmb_domain.Text = text;
        }
        private string GenerateNameDomain()
        {
            int n = 1;
            while (External.ds.Tables["domens"].Rows.Contains("NewDmn" + n.ToString()))
                n++;
            return "NewDmn" + n.ToString();
        }
        private void AddValue(string value, string domain)
        {
            External.ds.Tables["domens_params"].Rows.Add(new object[] { domain, value });
        }
        private void AddValue()
        {
            string text = cmb_default.Text.Trim();
            if (text != "" && !ContainsValue(cmb_default, text))
            {
                DialogResult dlg_res = MessageBox.Show("Да - добавить значение в текущий домен, нет - создать новый домен", "", MessageBoxButtons.YesNoCancel);
                switch (dlg_res)
                {
                    case DialogResult.Yes:
                        AddValue(text, cmb_domain.Text);
                        cmb_default.Text = text;
                        break;
                    case DialogResult.No:
                        AddDomain(GenerateNameDomain(), cmb_domain.Text);
                        AddValue(text, cmb_domain.Text);
                        cmb_default.Text = text;
                        break;
                }
            }
        }
        private void cmb_default_Leave(object sender, EventArgs e)
        {
            AddValue();
        }

        private void cmb_default_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
                AddValue();
        }
        #endregion




    }
}
